#pragma once

class BaseObjectBase;
class BaseObject;
class CNPC;

class ObjectManager
{
public:
	typedef list<BaseObjectBase*> Objects3D;
	typedef list<BaseObjectBase*> Objects2D;
	typedef list<BaseObjectBase*> ObjectNPCs;
private:
	// TODO delete pool
	Objects3D m_Objects3D;
	Objects2D m_Objects2D;
	ObjectNPCs m_ObjectsNPCs;
	bool currentlyRemovingObjects;

private:
	//**********************************************************************//
	//	Singleton															//
	//**********************************************************************//
	ObjectManager(void);
	ObjectManager(ObjectManager&);
	~ObjectManager(void);
	ObjectManager& operator=(ObjectManager&);

public:
	static ObjectManager* GetInstance() { static ObjectManager instance; return &instance; }
	//**********************************************************************//

	//**********************************************************************//
	//	Function Name: UpdateObjects										//
	//	Arguments: float _dt												//
	//	Return Type: void													//
	//	Return Notes: 														//
	//	Scope: public														//
	//	Last Modified: 5/26/2009 1:56:15 AM									//
	//	Purpose: Update all objects in the list								//
	//**********************************************************************//
	void UpdateObjects(float _dt);

	void RenderObjects();

	//**********************************************************************//
	//	Function Name: AddObject											//
	//	Arguments: BaseObject *const _object								//
	//	Return Type: void													//
	//	Return Notes: 														//
	//	Scope: public														//
	//	Last Modified: 5/26/2009 1:56:53 AM									//
	//	Purpose: Adds the given object to the list							//
	//**********************************************************************//
	void AddObject(BaseObjectBase* _object);

	//**********************************************************************//
	//	Function Name: RemoveObject											//
	//	Arguments: BaseObject *const _object								//
	//	Return Type: void													//
	//	Return Notes: 														//
	//	Scope: public														//
	//	Last Modified: 5/26/2009 1:57:31 AM									//
	//	Purpose: Removes the given object from the list and releases it		//
	//**********************************************************************//
	void RemoveObject(BaseObjectBase* _object);

	//**********************************************************************//
	//	Function Name: RemoveAllObjects										//
	//	Arguments: void														//
	//	Return Type: void													//
	//	Return Notes: 														//
	//	Scope: public														//
	//	Last Modified: 5/26/2009 1:59:23 AM									//
	//	Purpose: Removes all objects from the list and releases them		//
	//**********************************************************************//
	void RemoveAllObjects(void);

	//**********************************************************************//
	//	list<BaseObject*> m_n_Layer Accessor								//
	//**********************************************************************//
	Objects3D& GetObjects3D() { return m_Objects3D; }
	Objects2D& GetObjects2D() { return m_Objects2D; }
	//**********************************************************************//

	//**********************************************************************//
	//	bool currentlyRemovingObjects Accessor								//
	//**********************************************************************//
	bool IsCurrentlyRemovingAllObjects() const { return currentlyRemovingObjects; }
	//**********************************************************************//
};

DECLARE_SINGLETON_H(ObjectManager);

// TODO accumulate all delete calls in one update into vector, and just loop through the object list once
// like just make a "Delete Pool"